package com.jfl.service.impl.system;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.jfl.base.BaseServiceImpl;
import com.jfl.base.PageRequest;
import com.jfl.common.Constants;
import com.jfl.common.MessageKey;
import com.jfl.common.SqlMapperKey;
import com.jfl.config.Resources;
import com.jfl.exception.BusinessException;
import com.jfl.mapper.SysDeptMapper;
import com.jfl.mapper.SysUserMapper;
import com.jfl.mapper.SysUserPostMapper;
import com.jfl.mapper.SysUserRoleMapper;
import com.jfl.model.SysDept;
import com.jfl.model.SysUser;
import com.jfl.model.SysUserPost;
import com.jfl.model.SysUserRole;
import com.jfl.system.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 系统用户接口
 * 
 * @author 赵炎
 * @version [V1.00, 2018年11月29日]
 * @since V1.00
 */
@Component
@Service(version = "${jfl.version}")
public class SysUserServiceImpl extends BaseServiceImpl<SysUser, SysUserMapper> implements SysUserService
{
    @Autowired
    private SysDeptMapper sysDeptMapper;
    
    @Autowired
    private SysUserPostMapper sysUserPostMapper;
    
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    
    @Override
    public void init()
    {
        queryList(Maps.newHashMap());
    }
    
    /**
     * 重写方法
     * @param request
     * @param record
     * @return
     * @see com.jfl.base.BaseServiceImpl#selectList(com.jfl.base.PageRequest, com.jfl.base.BaseModel)
     */
    //@HystrixCommand(fallbackMethod = "fail")
    @Override
    public PageInfo<SysUser> selectList(PageRequest request, SysUser record)
    {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), request.getOrderBy());
        QueryWrapper<SysUser> wrapper = new QueryWrapper<SysUser>();
        if (record != null)
        {
            // 精确
            if (StringUtils.isNotBlank(record.getStatus()))
            {
                wrapper.eq(SqlMapperKey.STATUS, record.getStatus());
            }
            // 模糊
            if (StringUtils.isNotBlank(record.getUserName()))
            {
                wrapper.like(SqlMapperKey.USER_NAME, record.getUserName());
            }
            if (StringUtils.isNotBlank(record.getEmail()))
            {
                wrapper.like(SqlMapperKey.EMAIL, record.getEmail());
            }
            if (StringUtils.isNotBlank(record.getPhone()))
            {
                wrapper.like(SqlMapperKey.PHONE, record.getPhone());
            }
            if (record.getParentId() != null)
            {
                // 部门信息
                SysDept sysDept = this.sysDeptMapper.selectById(record.getDeptId());
                if (sysDept.getParentId() != 0)
                {
                    wrapper.eq(SqlMapperKey.DEPT_ID, record.getDeptId());
                }
                else
                {
                    Set<Long> set = Sets.newHashSet();
                    Map<String, Object> params = Maps.newHashMap();
                    params.put(SqlMapperKey.PARENT_ID, record.getDeptId());
                    List<SysDept> sysDeptList = this.sysDeptMapper.selectByMap(params);
                    for (SysDept dept : sysDeptList)
                    {
                        set.add(dept.getId());
                    }
                    if (!set.isEmpty())
                    {
                        wrapper.in(SqlMapperKey.DEPT_ID, set);
                    }
                }
                
            }
            if (record.getParams() != null)
            {
                if (StringUtils.isNotBlank(record.getParams().get("beginTime") + ""))
                {
                    wrapper.gt(SqlMapperKey.CREATE_TIME, record.getParams().get("beginTime") + "");
                }
                if (StringUtils.isNotBlank(record.getParams().get("endTime") + ""))
                {
                    wrapper.gt(SqlMapperKey.CREATE_TIME, record.getParams().get("endTime") + "");
                }
            }
        }
        // 系统中未删除数据
        wrapper.eq(SqlMapperKey.ENABLE, Constants.NO);
        List<SysUser> userList = this.mapper.selectList(wrapper);
        return new PageInfo<SysUser>(userList);
    }
    
    @Override
    public SysUser selectByUserName(String userName)
    {
        SysUser user = null;
        Map<String, Object> params = Maps.newHashMap();
        params.put(SqlMapperKey.USER_NAME, userName);
        params.put(SqlMapperKey.ENABLE, Constants.NO);
        List<SysUser> userList = this.mapper.selectByMap(params);
        List<Long> roleIds = Lists.newArrayList();
        List<Long> postIds = Lists.newArrayList();
        Map<String, Object> userPostMap = Maps.newHashMap();
        Map<String, Object> userRoleMap = Maps.newHashMap();
        if (userList != null && userList.size() > 0)
        {
            user = userList.get(0);
            SysDept dept = this.sysDeptMapper.selectById(user.getDeptId());
            user.setDept(dept);
            // 设置部门 注意redis的序列化与反序列化问题
            user.setDeptName(dept.getDeptName());
            userPostMap.put(SqlMapperKey.USER_ID, user.getId());
            List<SysUserPost> sysUserPostList = this.sysUserPostMapper.selectByMap(userPostMap);
            for (SysUserPost sysUserPost : sysUserPostList)
            {
                postIds.add(sysUserPost.getPostId());
            }
            if (!postIds.isEmpty())
            {
                user.setPostIds(postIds.toArray(new Long[postIds.size()]));
            }
            userRoleMap.put(SqlMapperKey.USER_ID, user.getId());
            List<SysUserRole> userRoleList = this.sysUserRoleMapper.selectByMap(userRoleMap);
            for (SysUserRole userRole : userRoleList)
            {
                roleIds.add(userRole.getRoleId());
            }
            if (!roleIds.isEmpty())
            {
                user.setRoleIds(roleIds.toArray(new Long[roleIds.size()]));
            }
        }
        return user;
    }
    
    @Override
    public SysUser queryById(Long id)
    {
        List<Long> roleIds = Lists.newArrayList();
        List<Long> postIds = Lists.newArrayList();
        Map<String, Object> userPostMap = Maps.newHashMap();
        Map<String, Object> userRoleMap = Maps.newHashMap();
        SysUser user = super.queryById(id);
        if (user != null && user.getEnable().intValue() == 1)
        {
            
            SysDept dept = this.sysDeptMapper.selectById(user.getDeptId());
            user.setDept(dept);
            userPostMap.put(SqlMapperKey.USER_ID, user.getId());
            List<SysUserPost> sysUserPostList = this.sysUserPostMapper.selectByMap(userPostMap);
            for (SysUserPost sysUserPost : sysUserPostList)
            {
                postIds.add(sysUserPost.getPostId());
            }
            if (!postIds.isEmpty())
            {
                user.setPostIds(postIds.toArray(new Long[postIds.size()]));
            }
            userRoleMap.put(SqlMapperKey.USER_ID, user.getId());
            List<SysUserRole> userRoleList = this.sysUserRoleMapper.selectByMap(userRoleMap);
            for (SysUserRole userRole : userRoleList)
            {
                roleIds.add(userRole.getRoleId());
            }
            if (!roleIds.isEmpty())
            {
                user.setRoleIds(roleIds.toArray(new Long[roleIds.size()]));
            }
        }
        
        return user;
    }
    
    /**
     * 保存用户信息
     * @param user
     * @return
     * @see com.jfl.system.SysUserService#saveUser(com.jfl.model.SysUser)
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int saveUser(SysUser user)
    {
        
        user.setUpdateTime(new Date());
        user.setCreateTime(new Date());
        user.setUpdateBy(user.getCreateBy());
        int result = this.mapper.insert(user);
        
        // 新增用户岗位关联
        insertUserPosts(user);
        // 新增用户角色关联
        insertUserRoles(user);
        return result;
    }
    
    /** 
     * 新增用户角色数据
     * @param user
     */
    private void insertUserRoles(SysUser user)
    {
        SysUserRole userRole = null;
        for (Long roleId : user.getRoleIds())
        {
            userRole = new SysUserRole();
            userRole.setRoleId(roleId);
            userRole.setUserId(user.getId());
            this.sysUserRoleMapper.insert(userRole);
        }
    }

    /** 
     * 新增用户岗位数据
     * @param user
     */
    private void insertUserPosts(SysUser user)
    {
        // TODO 后期整合批量更新操作
        SysUserPost userPost = null;
        for (Long postId : user.getPostIds())
        {
           userPost = new SysUserPost();
           userPost.setPostId(postId);
           userPost.setUserId(user.getId());
           this.sysUserPostMapper.insert(userPost);
        }
    }

    /**
     * 批量删除用户信息
     * @param list
     * @param currentUserId
     * @return
     * @see com.jfl.system.SysUserService#deleteUsers(java.util.List, java.lang.Long)
     */
    @Transactional()
    @Override
    public void deleteUsers(List<Long> list, Long currentUserId) throws BusinessException
    {
        for (Long userId : list)
        {
            if(userId.intValue() == 1)
            {
                throw new BusinessException(Resources.getMessage(MessageKey.ADMIN_CANNOT_DELETE));
            }
            // 删除用户信息
            this.mapper.deleteById(userId);
            // 删除用户岗位数据
            deleteUserPostById(userId);
            // 删除用户角色数据  修复原先删除用户删除了所有用户角色表数据
            this.sysUserRoleMapper.deleteByUserId(userId);
        }
    }

    /**
     * 重写方法
     * @param user
     * @return
     * @see com.jfl.system.SysUserService#countByUserName(com.jfl.model.SysUser)
     */
    @Override
    public String countByUserName(SysUser user)
    {
        SysUser u = this.mapper.selectByUserName(user.getUserName());
        Long id = user.getId() == null ? -1: user.getId();
        return result(u, id);
    }

    /**
     * 重写方法
     * @param user
     * @return
     * @see com.jfl.system.SysUserService#countByEmail(com.jfl.model.SysUser)
     */
    @Override
    public String countByEmail(SysUser user)
    {
        SysUser u = this.mapper.selectByEmail(user.getEmail());
        Long id = user.getId() == null ? -1: user.getId();
        return result(u, id);
    }

    /**
     * 重写方法
     * @param user
     * @return
     * @see com.jfl.system.SysUserService#countByPhone(com.jfl.model.SysUser)
     */
    @Override
    public String countByPhone(SysUser user)
    {
        SysUser u = this.mapper.selectByPhone(user.getPhone());
        Long id = user.getId() == null ? -1: user.getId();
        return result(u, id);
    }

    /**
     * 重写方法
     * @param user
     * @return
     * @see com.jfl.system.SysUserService#updateUser(com.jfl.model.SysUser)
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateUser(SysUser user)
    {
        int result = this.mapper.updateById(user);
        if (result == 0)
        {
            return Constants.ERROR;
        }
        // 删除用户岗位数据
        deleteUserPostById(user.getId());
        insertUserPosts(user);
        // 删除用户角色信息
        deleteUserRoleById(user.getId());
        insertUserRoles(user);
        return Constants.SUCCESS;
    }

    /** 
     * 根据用户Id删除用户角色信息
     * @param userId 用户id
     */
    private void deleteUserRoleById(Long userId)
    {
        this.sysUserRoleMapper.deleteByUserId(userId);
    }

    /** 
     * 根据用户Id删除用户岗位信息
     * @param userId 用户Id
     */
    private void deleteUserPostById(Long userId)
    {
        this.sysUserPostMapper.deleteByUserId(userId);
    }

    public String fail()
    {
        return "hystrix";
    }
}
